package teleporting;

import impsoft.scripting.ibot.builtin.ocr.NPCChat;
import impsoft.scripting.ibot.itemrec.ItemContains;
import impsoft.scripting.ibot.itemrec.ItemRegex;
import impsoft.scripting.ibot.structs.AryanTile;
import impsoft.utils.general.Timer;
import inventory.InventoryResult;

import java.util.regex.Pattern;

import base.DreamScript;
import base.DreamUtility;

public class TeleportUtils extends DreamUtility {

	public TeleportUtils(DreamScript cs) {
		super(cs);
	}

	public boolean doTeleportItem(TeleportItem item, String location) throws InterruptedException {
		AryanTile startLocation = cs.getLocation();
		TeleportType teleType = item.getTeleportType();

		if (!hasTeleportItem(item)) {
			cs.log("Did not detect teleport item");
		}

		if (teleType == TeleportType.TABLET && hasCharges(item)) {
			cs.log("Your teleport item has no charges");
		}

		if (teleType == TeleportType.TABLET) {
			InventoryResult result = cs.getInventoryUtils().doInventory(item.getName(), null, true);

			if (result.isSuccessful()) {
				waitForTeleport(startLocation);
			} else {
				cs.log("Failed to click teleport");
			}

			if (!startLocation.equals(cs.getLocation())) {
				cs.log("Detected teleport");
				return true;
			} else {
				cs.log("No teleporting detected");
			}
		} else if (teleType == TeleportType.BRACELET || teleType == TeleportType.AMULET
				|| teleType == TeleportType.NECKLACE || teleType == TeleportType.RING) {
			cs.log("Using " + item.getName() + " to teleport to " + location);
			if (cs.theTabs.Inventory.count(item.getName()) > 0) {
				cs.getInventoryUtils().doInventory(new ItemContains(item.getName()), "rub", true);

				NPCChat chat = null;
				for (Timer npcChatWait = new Timer(4000); (chat = cs.theNPCChatFinder.getNPCChat()) == null
						&& npcChatWait.isNotUp(); cs.sleep(100)) {
				}

				if (chat != null) {
					chat.selectContains(location.toLowerCase());
					waitForTeleport(startLocation);
					return !startLocation.equals(cs.getLocation());
				}
			} else {
				cs.theTabs.Equipment.key();

				if (cs.theTabs.Equipment.isWearing(item.getName())) {
					cs.theTabs.Equipment.doActionOnAll(item.getName(), location);
					waitForTeleport(startLocation);
					return !startLocation.equals(cs.getLocation());
				}
			}

		}

		return false;
	}

	public boolean hasTeleportItem(TeleportItem item) throws InterruptedException {
		return cs.theTabs.Inventory2.count(item.getName()) > 0 ? true : cs.theTabs.Equipment.isWearing(item.getName());
	}

	public boolean hasCharges(TeleportItem item) throws InterruptedException {
		if(item == null) {
			return false;
		}
		
		ItemRegex regex = new ItemRegex(Pattern.compile(item.getName() + (item.getTeleportType() != TeleportType.TABLET ? "  \\([1-4]\\" : ""), Pattern.CASE_INSENSITIVE));
		return cs.theTabs.Inventory2.count(regex) > 0 ? true : cs.theTabs.Equipment.isWearing(regex);
	}

	@Deprecated
	public boolean doJewelry(Jewellery jewellery, String location) throws InterruptedException {
		AryanTile startLocation = cs.getLocation();
		cs.log("Using " + jewellery.getName() + " to teleport to " + location);
		if (cs.theTabs.Inventory.count(jewellery.getName()) > 0) {
			cs.getInventoryUtils().doInventory(new ItemContains(jewellery.getName()), "rub", true);

			NPCChat chat = null;
			for (Timer npcChatWait = new Timer(4000); (chat = cs.theNPCChatFinder.getNPCChat()) == null
					&& npcChatWait.isNotUp(); cs.sleep(100)) {
			}

			if (chat != null) {
				chat.selectContains(location.toLowerCase());
				waitForTeleport(startLocation);
				return !startLocation.equals(cs.getLocation());
			}
		} else {
			cs.getTabHandler().setTab(cs.theTabs.Equipment);

			if (cs.theTabs.Equipment.isWearing(jewellery.getName())) {
				cs.theTabs.Equipment.doActionOnAll(jewellery.getName(), location);
				waitForTeleport(startLocation);
				return !startLocation.equals(cs.getLocation());
			}
		}

		return false;
	}

	@Deprecated
	public boolean hasTeleportTab(TeleportTab tab) throws InterruptedException {
		return cs.theTabs.Inventory.count(tab.getItemCondition()) > 0;
	}

	@Deprecated
	public boolean doTeleportTab(TeleportTab tab) throws InterruptedException {
		if (hasTeleportTab(tab)) {
			AryanTile startLocation = cs.getLocation();

			InventoryResult result = cs.getInventoryUtils().doInventory(tab.getItemCondition(), null, true);

			if (result.isSuccessful()) {
				waitForTeleport(startLocation);
			} else {
				cs.log("Failed to click teleport");
			}

			if (!startLocation.equals(cs.getLocation())) {
				cs.log("Detected teleport");
				return true;
			} else {
				cs.log("No teleporting detected");
			}
		}

		return false;
	}

	public void waitForTeleport(AryanTile currentLocation) throws InterruptedException {
		for (Timer teleport = new Timer(5000); teleport.isNotUp() && cs.getLocation().equals(currentLocation);) {
			cs.sleep(100);
		}
	}
}
